﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using log4net;
using System.Configuration;
using Impinj.OctaneSdk;
using GS1.Utilitario;
using GS1.Dato;
using GS1.Entidad;

namespace ControlVehiculoRFIDPN
{
    public partial class ControlVehiculoRFIDPN : ServiceBase
    {

        #region --- Variables y Propiedades ---
        Timer timerServicioLectura = new Timer();
        private static readonly ILog log = LogManager.GetLogger(typeof(ControlVehiculoRFIDPN));

        // Create a collection to hold all the ImpinjReader instances.
        private ImpinjReader reader = null;
        private Status status = null;

        private RFIDState estadoReader;
        private enum RFIDState
        {
            CONECTADO,
            DESCONECTADO
        }

        // Cabecera de identificacion de etiqueta
        private string IDENTIFICADOR_CAB_ETIQUETA = "0000";

        private ListaEtiqueta listaEtiqueta = new ListaEtiqueta();
        #endregion

        #region --- Constructor y Destructor ---

        public ControlVehiculoRFIDPN()
        {
            //Declara el evento cuando termina el timer
            timerServicioLectura.Elapsed += timerServicioLectura_Elapsed;
            //carga la configuracion del log
            log4net.Config.XmlConfigurator.Configure();

            InitializeComponent();
        }
        #endregion

        #region --- Eventos del Servicio ---

        protected override void OnStart(string[] args)
        {
            try
            {
                log.Debug("------------------------------");
                log.Debug("Iniciando Servicio Lectura ... v20141003.1200");
                log.Debug("------------------------------");
                log.Debug("Configuración de Antenas Entrada: ");
                log.Debug("Antena 1: " + ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA1]);
                //log.Debug("Antena 9: " + ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA2]);
                log.Debug("Configuración de Antenas Salida: ");
                log.Debug("Antena 17: " + ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA3]);
                //log.Debug("Antena 25: " + ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA4]);
                log.Debug("------------------------------");
                log.Debug("Filtro: Cabecera de código EPC - Hermes: " + ConfigurationManager.AppSettings[Constantes.IDENTIFICADOR_CAB_ETIQUETA]);

                // Estableciendo parametros del timer del servicio
                this.IDENTIFICADOR_CAB_ETIQUETA = ConfigurationManager.AppSettings[Constantes.IDENTIFICADOR_CAB_ETIQUETA];
                timerServicioLectura.Interval = 1000 * Convert.ToInt16(ConfigurationManager.AppSettings[Constantes.SEGUNDOS_ENTRE_CADA_VERIFICACION]);
                timerServicioLectura.Enabled = true;
                timerServicioLectura.Start();
                log.Debug("TimerServicioLectura.Start(): " + timerServicioLectura.Interval.ToString());

                // ------
                log.Debug("Iniciando conexion con Reader ...");
                this.estadoReader = RFIDState.DESCONECTADO;

                bool resultado = conectar();
                if (resultado)
                {
                    log.Debug("Se establecio conexion con Reader - " + ConfigurationManager.AppSettings[Constantes.IPREADER]);

                    resultado = iniciarLectura();
                    if (resultado)
                    {
                        log.Debug("Se inicio la lectura del Reader");
                    }
                }

                // Estableciendo intervalor del timer de limpiezas

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
        }

        protected override void OnStop()
        {
            try
            {
                timerServicioLectura.Enabled = false;

                log.Debug("-------------------------------");
                log.Debug("Deteniendo Servicio Lectura ... v20141003.1200");

                // -------
                log.Debug("Deteniendo conexion con el  Reader ... ");
                detenerLectura();

                bool resultado = desconectar();
                if (resultado)
                {
                    log.Debug("Se finalizo conexion con Reader - " + ConfigurationManager.AppSettings[Constantes.IPREADER]);
                }


            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
        }

        #endregion

        #region --- Evento del Timer ---
        private void timerServicioLectura_Elapsed(object sender, ElapsedEventArgs e)
        {
            //Listas donde se almacena la etiqueta que se ha pasado al otro lado indicando que ya termino
            ListaEtiqueta listaEtiquetasCabecera = new ListaEtiqueta();

            try
            {
                //Se detiene el reloj
                timerServicioLectura.Stop();

                #region -- descarga lista --
                int iLenghtListaEtiqueta = listaEtiqueta.Count();
                for (int i = 0; i < iLenghtListaEtiqueta; i++)
                {
                    Etiqueta etiqueta = listaEtiqueta[i];
                    //graba resultado en BD
                    new DatosLite().guardarListaEtiqueta(etiqueta);

                }
                //Elimina de la cola los datos que se cargaron
                listaEtiqueta.RemoveRange(0, iLenghtListaEtiqueta);
                #endregion

                #region ---datos del Request Metadata---
                //obtiene el Numero de serie del reader
                FeatureSet features = this.reader.QueryFeatureSet();
                RequestMetada requestMetadata = new RequestMetada();
                requestMetadata.remoteHost = features.SerialNumber;
                #endregion

                #region ---Carga los objetos de vehiculos ---
                //Ejecutar las tareas para evaluar el resultado
                listaEtiquetasCabecera = new DatosLite().ListaRegistroUnicoEtiquetas();
                foreach (Etiqueta etiquetaCebecera in listaEtiquetasCabecera)
                {
                    Etiqueta ultimaEtiqueta = new DatosLite().buscaUltimaLecturaEtiqueta(etiquetaCebecera);
                    if (validarTiempoLectura(ultimaEtiqueta.fechaInicio))
                    {
                        #region ---Evalua Etiquetas de Entrada ---
                        //Lista Entrada carga la lista sobre las etiquetas de movimiento
                        if (ultimaEtiqueta.antena.Equals(Constantes.ANTENNA3.ToString()) |
                            ultimaEtiqueta.antena.Equals(Constantes.ANTENNA4.ToString()))
                        {
                            Etiqueta primeraEtiqueta = new DatosLite().buscaPrimeraLecturaEtiqueta(etiquetaCebecera);
                            //Valida que la etiqueta realmente este de entrada
                            if (primeraEtiqueta.antena.Equals(Constantes.ANTENNA1.ToString()) |
                                primeraEtiqueta.antena.Equals(Constantes.ANTENNA2.ToString()))
                            {
                                //Se crea el objeto a enviar
                                ControlVehiculoRFID controlVehiculoRFID = new ControlVehiculoRFID();
                                controlVehiculoRFID.codigoEPC = primeraEtiqueta.epc.Replace(" ", "");
                                controlVehiculoRFID.codigoDireccionVehiculo = Constantes.ENTRADA;
                                controlVehiculoRFID.descripcionPuerta = ConfigurationManager.AppSettings[Constantes.PUERTA].ToString();
                                controlVehiculoRFID.fechaFinalMovimiento = ultimaEtiqueta.fechaInicio;
                                controlVehiculoRFID.fechaInicioMovimiento = primeraEtiqueta.fechaInicio;

                                if (!new DatosLite().validarMovimientoControlVehiculo(controlVehiculoRFID))
                                {
                                    new DatosLite().guardarMovimientoControlVehiculo(controlVehiculoRFID);
                                }
                            }
                        }
                        #endregion

                        #region ---Evalua Etiquetas de Salida ---
                        //Lista Salida carga la lista sobre las etiquetas de movimiento
                        else if (ultimaEtiqueta.antena.Equals(Constantes.ANTENNA1.ToString()) |
                                  ultimaEtiqueta.antena.Equals(Constantes.ANTENNA2.ToString()))
                        {
                            Etiqueta primeraEtiqueta = new DatosLite().buscaPrimeraLecturaEtiqueta(etiquetaCebecera);
                            //Valida que la etiqueta realmente este de salida
                            if (primeraEtiqueta.antena.Equals(Constantes.ANTENNA3.ToString()) |
                            primeraEtiqueta.antena.Equals(Constantes.ANTENNA4.ToString()))
                            {
                                //Se crea el objeto a enviar
                                ControlVehiculoRFID controlVehiculoRFID = new ControlVehiculoRFID();
                                controlVehiculoRFID.codigoEPC = primeraEtiqueta.epc.Replace(" ", "");
                                controlVehiculoRFID.codigoDireccionVehiculo = Constantes.SALIDA;
                                controlVehiculoRFID.descripcionPuerta = ConfigurationManager.AppSettings[Constantes.PUERTA].ToString();
                                controlVehiculoRFID.fechaFinalMovimiento = ultimaEtiqueta.fechaInicio;
                                controlVehiculoRFID.fechaInicioMovimiento = primeraEtiqueta.fechaInicio;

                                if (!new DatosLite().validarMovimientoControlVehiculo(controlVehiculoRFID))
                                {
                                    new DatosLite().guardarMovimientoControlVehiculo(controlVehiculoRFID);
                                }
                            }

                        }
                        #endregion

                        //Borrar todos los registros de esa etiqueta
                        new DatosLite().eliminarListaEtiqueta(ultimaEtiqueta);
                    }
                }
                listaEtiquetasCabecera = null;
                #endregion

                #region---enviaXML----
                ListaControlVehiculoRFID listaVehiculo = new DatosLite().ListaRegistroListaTotalMovimientoControlVehiculo();
                foreach (ControlVehiculoRFID controlVehiculoRFID in listaVehiculo)
                {
                    try
                    {
                        //Llama al objeto en java con la cadena en XML en post
                        string contenidoXML = string.Empty;
                        Operacion operacion = new Operacion();

                        operacion.controlVehiculoRFID = new ControlVehiculoRFID();
                        operacion.controlVehiculoRFID = controlVehiculoRFID;
                        operacion.requestMetadata = new RequestMetada();
                        operacion.requestMetadata = requestMetadata;


                        // Instanciando y ejecutando llamada al ServicioREST
                        ConexionREST conexionREST = new ConexionREST();
                        contenidoXML = conexionREST.ejecutarTrama(operacion);
                        Boolean bModifica = new DatosLite().modificarMovimientoControlVehiculo(controlVehiculoRFID);
                    }

                    catch (Exception ex)
                    {
                        log.Error(ex.Message, ex);
                        log.Debug("Datos de Vehiculo: " + controlVehiculoRFID.codigoEPC +
                                  " Puerta: " + controlVehiculoRFID.descripcionPuerta +
                                  " Direccion: " + controlVehiculoRFID.codigoDireccionVehiculo +
                                  " Hora Inicial: " + controlVehiculoRFID.fechaInicioMovimiento.ToString() +
                                  " Hora Final: " + controlVehiculoRFID.fechaFinalMovimiento.ToString());
                    }
                }
                listaVehiculo = null;

                #endregion

                #region---Limpia Lista Etiqueta---
                //Limpia de la lista si la lectura ha pasado más del tiempo indicado

                listaEtiquetasCabecera = new DatosLite().ListaRegistroUnicoEtiquetas();
                foreach (Etiqueta etiqueta in listaEtiquetasCabecera)
                {
                    //Valido que no se haya visto en X tiempo
                    if (validarTiempoLimpiar(etiqueta.fechaInicio))
                    {
                        //Si no se ha visto en X tiempo, entonces se elimina
                        new DatosLite().eliminarListaEtiqueta(etiqueta);
                    }
                }
                listaEtiquetasCabecera = null;
                #endregion

                #region --borrar datahistorica --
                new DatosLite().eliminarMovimientoControlVehiculo(DateTime.Now.AddDays(-2));
                new DatosLite().eliminarListaEtiquetaRemanente(DateTime.Now.AddDays(-2));

                #endregion

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
            finally
            {
                timerServicioLectura.Start();
            }
        }
        #endregion

        #region --- Procedimientos OctaneSDK ---
        private void inicializarReader()
        {
            this.reader = new ImpinjReader();
            // Capturado eventos de lectura de Tags
            this.reader.TagsReported += OnTagsReported;
        }

        private void finalizarReader()
        {
            this.reader.TagsReported -= OnTagsReported;
            this.reader = null;
        }

        private bool conectar()
        {
            bool resultado = false;
            try
            {
                inicializarReader();

                this.reader.Connect(ConfigurationManager.AppSettings[Constantes.IPREADER], Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.PORT]));

                this.reader.ApplyDefaultSettings();

                Settings settings = reader.QueryDefaultSettings();

                int indiceReaderMode = 0;
                indiceReaderMode = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.INDICE_READER_MODE]);

                // Estableciendo Reader Mode
                switch (indiceReaderMode)
                {
                    case 0://AutoSet Dense Reader
                        settings.ReaderMode = ReaderMode.AutoSetDenseReader;
                        break;
                    case 1://AutoSet Single Reader
                        settings.ReaderMode = ReaderMode.AutoSetSingleReader;
                        break;
                    case 2://Max Throughput
                        settings.ReaderMode = ReaderMode.MaxThroughput;
                        break;
                    case 3://Hybrid Mode
                        settings.ReaderMode = ReaderMode.Hybrid;
                        break;
                    case 4://Dense Reader (M=4)
                        settings.ReaderMode = ReaderMode.DenseReaderM4;
                        break;
                    case 5://Dense Reader (M=8)
                        settings.ReaderMode = ReaderMode.DenseReaderM8;
                        break;
                    case 6://MaxMiller
                        settings.ReaderMode = ReaderMode.MaxMiller;
                        break;
                }

                int indiceSearchMode = 0;
                indiceSearchMode = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.INDICE_SEARCH_MODE]);

                // Estableciendo Search Mode
                switch (indiceSearchMode)
                {
                    case 0://Dual Target
                        settings.SearchMode = SearchMode.DualTarget;
                        break;
                    case 1://Single Target Inventory
                        settings.SearchMode = SearchMode.SingleTarget;
                        break;
                    case 2://Single Target w/Supression
                        settings.SearchMode = SearchMode.TagFocus;
                        break;
                    case 3://Desconocido
                        settings.SearchMode = SearchMode.ReaderSelected;
                        break;
                }

                // Estableciendo Sesion
                settings.Session = Convert.ToUInt16(ConfigurationManager.AppSettings[Constantes.INDICE_SESSION]);

                settings.Antennas.DisableAll();

                settings.Antennas.GetAntenna(1).IsEnabled = ConfigurationManager.AppSettings[Constantes.ACTIVAR_ANTENA1].ToString().Equals(Constantes.SI);
                settings.Antennas.GetAntenna(9).IsEnabled = ConfigurationManager.AppSettings[Constantes.ACTIVAR_ANTENA2].ToString().Equals(Constantes.SI);
                settings.Antennas.GetAntenna(17).IsEnabled = ConfigurationManager.AppSettings[Constantes.ACTIVAR_ANTENA3].ToString().Equals(Constantes.SI);
                settings.Antennas.GetAntenna(25).IsEnabled = ConfigurationManager.AppSettings[Constantes.ACTIVAR_ANTENA4].ToString().Equals(Constantes.SI);

                if (settings.Antennas.GetAntenna(1).IsEnabled)
                {
                    settings.Antennas.GetAntenna(1).MaxRxSensitivity = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA1]);
                    settings.Antennas.GetAntenna(1).MaxTransmitPower = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA1]);
                    settings.Antennas.GetAntenna(1).TxPowerInDbm = Convert.ToDouble(ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA1]);
                    settings.Antennas.GetAntenna(1).RxSensitivityInDbm = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.SENSIBILIDAD_ANTENA1]);
                }

                if (settings.Antennas.GetAntenna(9).IsEnabled)
                {
                    settings.Antennas.GetAntenna(9).MaxRxSensitivity = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA2]);
                    settings.Antennas.GetAntenna(9).MaxTransmitPower = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA2]);
                    settings.Antennas.GetAntenna(9).TxPowerInDbm = Convert.ToDouble(ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA2]);
                    settings.Antennas.GetAntenna(9).RxSensitivityInDbm = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.SENSIBILIDAD_ANTENA2]);
                }

                if (settings.Antennas.GetAntenna(17).IsEnabled)
                {
                    settings.Antennas.GetAntenna(17).MaxRxSensitivity = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA3]);
                    settings.Antennas.GetAntenna(17).MaxTransmitPower = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA3]);
                    settings.Antennas.GetAntenna(17).TxPowerInDbm = Convert.ToDouble(ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA3]);
                    settings.Antennas.GetAntenna(17).RxSensitivityInDbm = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.SENSIBILIDAD_ANTENA3]);
                }

                if (settings.Antennas.GetAntenna(25).IsEnabled)
                {
                    settings.Antennas.GetAntenna(25).MaxRxSensitivity = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA4]);
                    settings.Antennas.GetAntenna(25).MaxTransmitPower = (Constantes.SI == ConfigurationManager.AppSettings[Constantes.TODA_CAPACIDAD_ANTENA4]);
                    settings.Antennas.GetAntenna(25).TxPowerInDbm = Convert.ToDouble(ConfigurationManager.AppSettings[Constantes.POTENCIA_ANTENA4]);
                    settings.Antennas.GetAntenna(25).RxSensitivityInDbm = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.SENSIBILIDAD_ANTENA4]);
                }

                settings.Report.IncludeAntennaPortNumber = true;
                settings.Report.IncludePeakRssi = true;
                settings.Report.IncludePhaseAngle = true;
                settings.Report.IncludeChannel = true;
                settings.Report.IncludeFirstSeenTime = true;
                settings.Report.IncludeLastSeenTime = true;
                settings.Report.IncludeSeenCount = true;
                settings.Report.IncludeFastId = true;
                settings.Report.Mode = ReportMode.Individual;

                // Estableciendo los nuevos parametros de configuracion
                this.reader.ApplySettings(settings);

                // Estableciendo identificador(MAC) del ReaderRFID
                //this.reader.ReaderIdentity = this.reader.QueryFeatureSet().ReaderIdentity;
                this.status = this.reader.QueryStatus();

                this.estadoReader = RFIDState.CONECTADO;

                resultado = true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return resultado;
        }

        private bool desconectar()
        {
            bool resultado = false;

            try
            {
                if (this.estadoReader == RFIDState.DESCONECTADO) { return true; }

                resultado = detenerLectura();

                if (resultado == false)
                {
                    this.reader.Disconnect();
                }

                finalizarReader();

                this.estadoReader = RFIDState.DESCONECTADO;

                resultado = true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return resultado;
        }

        private string obtenerInformacion()
        {
            StringBuilder cadenaInformacion = null;
            try
            {
                if (this.estadoReader == RFIDState.DESCONECTADO)
                {
                    log.Debug("Primero debe establecer conexion con el Reader");
                    return string.Empty;
                }

                cadenaInformacion = new StringBuilder();

                FeatureSet features = this.reader.QueryFeatureSet();

                cadenaInformacion.Append("Nombre del Modelo: " + features.ModelName);
                cadenaInformacion.Append(Environment.NewLine);
                cadenaInformacion.Append("Numero del Modelo: " + features.ModelNumber);
                cadenaInformacion.Append(Environment.NewLine);
                cadenaInformacion.Append("Numero de Serie: " + features.SerialNumber);
                cadenaInformacion.Append(Environment.NewLine);
                //cadenaInformacion.Append("Indetificación del Reader: " + this.status.ReaderIdentity.ToString());
                //cadenaInformacion.Append(Environment.NewLine);
                cadenaInformacion.Append("Version del Firmware: " + features.FirmwareVersion);
                cadenaInformacion.Append(Environment.NewLine);
                //cadenaInformacion.Append("Version del Octane software: " + features.SoftwareVersion);
                //cadenaInformacion.Append(Environment.NewLine);
                cadenaInformacion.Append("Cantidad de Antenas: " + features.AntennaCount);

                log.Debug(cadenaInformacion.ToString());
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return cadenaInformacion.ToString();
        }

        private bool obtenerEstadoConexion()
        {
            bool conectado = false;
            try
            {
                Status status = this.reader.QueryStatus();
                conectado = status.IsConnected == true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return conectado;
        }

        private bool iniciarLectura()
        {
            bool resultado = false;
            try
            {
                if (this.estadoReader == RFIDState.DESCONECTADO) { return resultado; }

                if (!this.reader.QueryStatus().IsSingulating)
                {
                    this.reader.Start();
                }

                resultado = true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return resultado;
        }

        private bool detenerLectura()
        {
            bool resultado = false;
            try
            {
                if (this.estadoReader == RFIDState.DESCONECTADO)
                {
                    log.Debug("Primero debe establecer conexion con el Reader");
                    return resultado;
                }

                if (this.reader.QueryStatus().IsSingulating)
                {
                    this.reader.Stop();
                }

                resultado = true;

            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }

            return resultado;
        }

        #endregion

        #region --- Eventos del Reader ---
        private void OnTagsReported(ImpinjReader sender, TagReport report)
        {
            // This event handler is called asynchronously when tag reports are available.
            if (this.estadoReader == RFIDState.DESCONECTADO) { return; }

            try
            {
                // Validar si hay tag leidos
                if (report.Tags.Count == 0) { return; }

                // Validar si esta activo el comando de Lectura de Tag
                if (!ConfigurationManager.AppSettings[Constantes.ACTIVAR_COMANDO_LEC].ToString().Equals(Constantes.SI))
                { return; }

                // Loop por cada etiqueta que lea del report.
                foreach (Tag tag in report)
                {
                    // Validar que sea una etiqueta con la estructura de Hermes
                    if (!esEtiquetaValida(tag.Epc.ToString())) { return; }
                    //Registra Etiqueta
                    Etiqueta etiqueta = new Etiqueta();
                    etiqueta.epc = tag.Epc.ToString();
                    etiqueta.fechaInicio = DateTime.Now;//Es la dia y hora en que se lee la etiqueta en ese momento
                    etiqueta.fechaFinal = tag.LastSeenTime.LocalDateTime;
                    etiqueta.antena = tag.AntennaPortNumber.ToString();
                    etiqueta.tipo = Constantes.TIPOINICIO;

                    listaEtiqueta.Add(etiqueta);

                    if (ConfigurationManager.AppSettings[Constantes.ACTIVAR_LOG].ToString().Equals(Constantes.SI))
                    {
                        log.Debug("Lectura de Etiqueta: "+etiqueta.epc.Replace(" ","") +
                                  " | Fecha y Hora de Lectura: " + etiqueta.fechaInicio.ToString() +
                                  " | Antena: " + etiqueta.antena );

                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
        }

        #endregion

        #region --- Eventos del Personalizados ---

        private bool validarTiempoLimpiar(DateTime tiempoLecturaRegistrado)
        {
            TimeSpan tiempoDiferencia = DateTime.Now - tiempoLecturaRegistrado;
            int tiempoEsperaLectura = 0;

            tiempoEsperaLectura = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.LLAVE_TIEMPO_LIMPIA_LISTA]);

            return tiempoDiferencia.TotalSeconds >= tiempoEsperaLectura;
        }

        private bool validarTiempoLectura(DateTime tiempoLecturaRegistrado)
        {
            TimeSpan tiempoDiferencia = DateTime.Now - tiempoLecturaRegistrado;
            int tiempoEsperaLectura = 0;

            tiempoEsperaLectura = Convert.ToInt32(ConfigurationManager.AppSettings[Constantes.LLAVE_TIEMPO_ESPERA_LECTURA]);

            return tiempoDiferencia.TotalSeconds >= tiempoEsperaLectura;
        }

        private bool esEtiquetaValida(string epc)
        {
            epc = epc.Trim();
            if (epc.Length.Equals(29))
            {
                string cabecera = epc.Substring(0, 16);
                return cabecera.Equals(this.IDENTIFICADOR_CAB_ETIQUETA);
            }
            else
                return false;
        }

        static List<Etiqueta> registroTemporal(Etiqueta etiqueta, List<Etiqueta> listaTemporal, String tipo)
        {
            List<Etiqueta> ListaEtiquetaAyuda = new List<Etiqueta>();
            etiqueta.tipo = tipo;

            foreach (Etiqueta etiquetaLeida in listaTemporal)
            {
                //Si la etiqueta existe en la lista temporal, se retira
                if (!etiquetaLeida.epc.Equals(etiqueta.epc))
                {
                    ListaEtiquetaAyuda.Add(etiquetaLeida);
                }
            }
            //Siempre se agrega la etiqueta en Etiqueta Ayuda por que ha sido retirada y se agrega con nuevos datos
            ListaEtiquetaAyuda.Add(etiqueta);
            return ListaEtiquetaAyuda;
        }
        #endregion
    }
}
